package com.leyou.service;

import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.threadlocals.UserHolder;
import com.leyou.common.utils.JsonUtils;
import com.leyou.entity.Cart;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String KEY_PREFIX = "ly:cart:uid:";


    /**
     * 添加商品到购物车
     * 如果购物车有商品就修改
     * 没有就添加购物车
     *
     * @param cart
     * @return
     */
    public void addCart(Cart cart) {
        //取出用户信息
        String key = KEY_PREFIX + UserHolder.getUser().getId();

        //构建双层Map结构的购物车，key是用户名，hkey是skuId,hval是json格式的商品信息
        BoundHashOperations<String, String, String> ops = redisTemplate.boundHashOps(key);

        add(cart,ops);
    }

    /**
     * 批量新增，
     * 当用户登录时，我们就将用户在未登录状态下添加到购物车的商品一次性添加到redis中
     *
     * @param cartList
     */
    public void addCartList(List<Cart> cartList) {
        //取出用户信息
        String key = KEY_PREFIX + UserHolder.getUser().getId();

        //构建双层Map结构的购物车，key是用户名，hkey是skuId,hval是json格式的商品信息
        BoundHashOperations<String, String, String> ops = redisTemplate.boundHashOps(key);

        for (Cart cart : cartList) {
            add(cart,ops);
        }
    }

    /**
     * 抽取的新增单个商品的方法
     */
    private void add(Cart cart, BoundHashOperations<String, String, String> ops) {
        //获取商品 id
        String hashKey = cart.getSkuId().toString();

        //获取商品数量
        Integer num = cart.getNum();

        //判断购物车中是否有此商品
        Boolean bool = ops.hasKey(hashKey);

        //有此商品
        if (bool != null && bool) {
            String cartOld = ops.get(hashKey);
            cart = JsonUtils.toBean(cartOld, Cart.class);

            cart.setNum(num + cart.getNum());
        }

        ops.put(hashKey, JsonUtils.toString(cart));
    }


    /**
     * 查询用户的购物车信息
     *
     * @return
     */
    public List<Cart> queryCart() {
        //取出用户信息
        String key = KEY_PREFIX + UserHolder.getUser().getId();

        //判断是否有此用户的购物车
        Boolean bool = redisTemplate.hasKey(key);
        if (bool == null || !bool) {
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }

        //构建双层Map结构的购物车，key是用户名，hkey是skuId,hval是json格式的商品信息
        BoundHashOperations<String, String, String> ops = redisTemplate.boundHashOps(key);

        //判断是否有数据
        Long size = ops.size();
        if (size == null || size < 0) {
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }

        List<String> values = ops.values();

        return values.stream().map(json -> JsonUtils.toBean(json, Cart.class)).collect(Collectors.toList());
    }

    /**
     * 修改商品数量
     *
     * @param id
     * @param num
     */
    public void updateCart(Long id, Integer num) {
        //取出用户信息
        String key = KEY_PREFIX + UserHolder.getUser().getId();

        //构建双层Map结构的购物车，key是用户名，hkey是skuId,hval是json格式的商品信息
        BoundHashOperations<String, String, String> ops = redisTemplate.boundHashOps(key);

        String hkey = id.toString();

        Boolean bool = ops.hasKey(hkey);

        if (bool == null || !bool) {
            log.error("购物车商品不存在，用户：{}, 商品：{}", key, hkey);
            throw new LyException(ExceptionEnum.RESOURCE_NOT_FOUND);
        }

        //根据商品id，取出商品
        String goods = ops.get(hkey);

        Cart cart = JsonUtils.toBean(goods, Cart.class);

        cart.setNum(num);

        ops.put(hkey, JsonUtils.toString(cart));
    }

    /**
     * 从购物车中删除某个商品
     *
     * @param id
     */
    public void deleteGoods(Long id) {
        //取出用户信息
        String key = KEY_PREFIX + UserHolder.getUser().getId();

        //构建双层Map结构的购物车，key是用户名，hkey是skuId,hval是json格式的商品信息
        BoundHashOperations<String, String, String> ops = redisTemplate.boundHashOps(key);
        ops.delete(id.toString());
    }


}
